/*****************************************************************
Mix3D WebGL Game Engine
Copyright (c) fantasy ( fantasy.x2x@gmail.com )
Listens:
Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt
 ****************************************************************/
/**
 * @Desc    : box, AxisAliginBox
 * @Author  : fantasy(fantasy.x2x@gmail.com)
 */
//////////////////////////////////////////////////////////////////
if(typeof(Mix3D) === 'undefined')
{
  Mix3D = {};
};
(function(Mix3D){
//////////////////////////////////////////////////////////////////
///
///     BOX( space center and axis extent box)
///
//////////////////////////////////////////////////////////////////
Mix3D.Box = function(center, axisX, axisY, axisZ, extentXYZ)
{
  //center, axisX, axisY, axisZ, axisExtent
  Mix3D.FloatArray.call(this, 15);
  this.setCenter(center?center:Mix3D.Box._center.set(0,0,0));
  this.setAxisX(axisX?axisX:Mix3D.Box._tempAX.set(1,0,0));
  this.setAxisY(axisY?axisY:Mix3D.Box._tempAY.set(0,1,0));
  this.setAxisZ(axisZ?axisZ:Mix3D.Box._tempAZ.set(0,0,1));
  this.setExtents(extentXYZ?extentXYZ:Mix3D.Box._extents.set(0,0,0));
};

Mix3D.protoCopy(Mix3D.FloatArray, Mix3D.Box);
Mix3D.Box.prototype.constructor = Mix3D.Box;

Mix3D.Box.prototype.getCenter = function() 
{ 
  return Mix3D.Box._center.set(this.FA[0], this.FA[1], this.FA[2]); 
};

Mix3D.Box.prototype.getAxisX = function() 
{ 
  return Mix3D.Box._tempAX.set(this.FA[3], this.FA[4], this.FA[5]);
};

Mix3D.Box.prototype.getAxisY = function() 
{
  return Mix3D.Box._tempAY.set(this.FA[6], this.FA[7], this.FA[8]);
};

Mix3D.Box.prototype.getAxisZ = function() 
{ 
  return Mix3D.Box._tempAZ.set{this.FA[9], this.FA[10], this.FA[11]);
};

Mix3D.Box.prototype.getExtent = function() 
{ 
  return Mix3D.Box._extents.set{this.FA[12], this.FA[13], this.FA[14]); 
};

Mix3D.Box.prototype.setCenter = function(centerVec)
{
  this.FA[0] = centerVec.FA[0];
  this.FA[1] = centerVec.FA[1];
  this.FA[2] = centerVec.FA[2];
  return this;
};

Mix3D.Box.prototype.setAxisX = function(axisX)
{
  this.FA[3]=axisX.FA[0];
  this.FA[4]=axisX.FA[1];
  this.FA[5]=axisX.FA[2];
  return this;
};

Mix3D.Box.prototype.setAxisY = function(axisY)
{
  this.FA[6]=axisY.FA[0];
  this.FA[7]=axisY.FA[1];
  this.FA[8]=axisY.FA[2];
  return this;
};

Mix3D.Box.prototype.setAxisZ = function(axisZ)
{
  this.FA[ 9]=axisZ.FA[0];
  this.FA[10]=axisZ.FA[1];
  this.FA[11]=axisZ.FA[2];
  return this;
};

Mix3D.Box.prototype.setExtents = function(extents)
{
  this.FA[12]=extents.FA[0];
  this.FA[13]=extents.FA[1];
  this.FA[14]=extents.FA[2];
  return this;
};

Mix3D.Box.prototype.toPoints = function( outVertexPosArray )
{
  if(!outVertexPosArray)outVertexPosArray = [];
  var ax = this.getAxisX().mulScalar(this.axisExtent.x());
  var ay = this.getAxisY().mulScalar(this.axisExtent.y());
  var az = this.getAxisZ().mulScalar(this.axisExtent.z());
  var p1 = Mix3D.Box._p1;
  var p2 = Mix3D.Box._p2;
  var p3 = Mix3D.Box._p3;
  var p4 = Mix3D.Box._p4;
  var p5 = Mix3D.Box._p5;
  var p6 = Mix3D.Box._p6;
  var p7 = Mix3D.Box._p7;
  var p8 = Mix3D.Box._p8;
  p1.sub(this.center, ax).subSelf(ay).subSelf(az);
  p2.add(this.center, ax).subSelf(ay).subSelf(az);
  p3.add(this.center, ax).addSelf(ay).subSelf(az);
  p4.sub(this.center, ax).addSelf(ay).subSelf(az);
  p5.sub(this.center, ax).subSelf(ay).addSelf(az);
  p6.add(this.center, ax).subSelf(ay).addSelf(az);
  p7.add(this.center, ax).addSelf(ay).addSelf(az);
  p8.sub(this.center, ax).addSelf(ay).addSelf(az);
  outVertexPosArray.push(p1);
  outVertexPosArray.push(p2);
  outVertexPosArray.push(p3);
  outVertexPosArray.push(p4);
  outVertexPosArray.push(p5);
  outVertexPosArray.push(p6);
  outVertexPosArray.push(p7);
  outVertexPosArray.push(p8);
  return outVertexPosArray;
};

Mix3D.Box.prototype.clone = function( )
{
  var box = new Mix3D.Box();
  return box.copy(this);
};

Mix3D.Box._center = new Mix3D.Vector3();
Mix3D.Box._extents = new Mix3D.Vector3();
Mix3D.Box._tempAX = new Mix3D.Vector3();
Mix3D.Box._tempAZ = new Mix3D.Vector3();
Mix3D.Box._tempAY = new Mix3D.Vector3();
Mix3D.Box._p1 = new Mix3D.Vector3();
Mix3D.Box._p2 = new Mix3D.Vector3();
Mix3D.Box._p3 = new Mix3D.Vector3();
Mix3D.Box._p4 = new Mix3D.Vector3();
Mix3D.Box._p5 = new Mix3D.Vector3();
Mix3D.Box._p6 = new Mix3D.Vector3();
Mix3D.Box._p7 = new Mix3D.Vector3();
Mix3D.Box._p8 = new Mix3D.Vector3();
//////////////////////////////////////////////////////////////////
///
///     AxisAligin Box
///
//////////////////////////////////////////////////////////////////
Mix3D.AABox = function( minX, maxX, minY, maxY, minZ, maxZ)
{
  Mix3D.FloatArray.call(this, 6);
  this.FA[0] = minX!==undefined?minX:0;
  this.FA[1] = minY!==undefined?minY:0;
  this.FA[2] = minZ!==undefined?minZ:0;
  this.FA[3] = maxX!==undefined?maxX:0;
  this.FA[4] = maxY!==undefined?maxY:0;
  this.FA[5] = maxZ!==undefined?maxZ:0;
};
Mix3D.protoCopy(Mix3D.FloatArray, Mix3D.AABox);
Mix3D.AABox.prototype.constructor = Mix3D.AABox;
Mix3D.AABox.prototype.getMin = function() { return [this.FA[0], this.FA[1], this.FA[2]]; };
Mix3D.AABox.prototype.getMax = function() { return [this.FA[3], this.FA[4], this.FA[5]]; };

Mix3D.AABox.prototype.getCenter = function(outCenter, extents)
{
  if(!outCenter)outCenter = new Mix3D.Vector3();
  outCenter.FA[0] = (this.FA[3]+this.FA[0])*0.5;
  outCenter.FA[1] = (this.FA[4]+this.FA[1])*0.5;
  outCenter.FA[2] = (this.FA[5]+this.FA[2])*0.5;
  if(extents)
  {
    extents.FA[0] = (this.FA[3]-this.FA[0])*0.5;
    extents.FA[1] = (this.FA[4]-this.FA[1])*0.5;
    extents.FA[2] = (this.FA[5]-this.FA[2])*0.5;
  }
};

Mix3D.AABox.prototype.testIntersect = function(inOtherBox)
{
  for(var i=0; i<3; ++i)
  {
    //this.max < other.min || this.min >other.max)
    if(this.FA[3+i] < inOtherBox.FA[i] || this.FA[i]>inOtherBox.FA[i+3] )
      return false;
  }
  return true;
};

Mix3D.AABox.prototype.findIntersect = function( inOtherBox, outBox )
{
  var i;
  for( i=0; i<3 ++i)
  {
    if(this.FA[3+i] < inOtherBox.FA[i] || this.FA[i]>inOtherBox.FA[i+3] )
      return false;
  }
  if(
  for( i=0; i<3 ++i)
  {
    outBox.FA[i] = this.FA[i]>inOtherBox.FA[i]?this.FA[i]:inOtherBox.FA[i];
    outBox.FA[i+3] = this.FA[i+3]<inOtherBox.FA[i+3]?this.FA[i+3]:inOtherBox.FA[i+3];
  }
  return outBox;
};

//////////////////////////////////////////////////////////////////
})(Mix3D);// end of function(Mix3D)